package Java_Concurrency_in_Practice.futureTask;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

import Java_Concurrency_in_Practice.xinhaoliang.DataLoadException;

/**
 * Future.get 的行为取决于任务的状态, 如果任务已经完成, 那么get会立即返回结果.
 * 否则get将阻塞任务直到进入完成状态, 然后返回结果或抛出异常.<br>
 * FutureTask将计算结果从执行计算的线程传递到这个获取结果的线程, 
 * 而FutureTask的规范确保了这种传递过程能实现结果的安全发布.
 * @author xiangke
 *
 */
public class Preloader {

	private final FutureTask<ProductInfo> feture = new FutureTask<ProductInfo>(new Callable<ProductInfo>() {
		@Override
		public ProductInfo call() throws Exception {
			return loadProductInfo();
		}
	});
	
	private final Thread thread = new Thread();
	
	public void start() {
		thread.start();
	}
	
	public ProductInfo get() throws InterruptedException, ExecutionException {
		try {
			return feture.get();
		} catch (ExecutionException e) {
			Throwable cause = e.getCause();
			if (cause instanceof DataLoadException) {
				throw (DataLoadException)cause;
			} else {
				throw launderThrowable(cause);
			}
		}
	}
	
	
	public static RuntimeException launderThrowable(Throwable cause) {
		if (cause instanceof RuntimeException) {
			return (RuntimeException)cause;
		} else if (cause instanceof Error) {
			throw (Error)cause;
		} else {
			throw new IllegalStateException();
		}
	}

	/** 可能是一个长时间的计算 */
	private ProductInfo loadProductInfo() {
		return new ProductInfo();
	}
}
